// CSVViewer.cpp : Implementation of CCSVViewer
#include "stdafx.h"
#include "PGLShell.h"
#include "CSVViewer.h"


/////////////////////////////////////////////////////////////////////////////
// CCSVViewer

CCSVViewer::CCSVViewer()
{
	m_hCurveBmp = LoadBitmap ( _Module.GetModuleInstance(),
		MAKEINTRESOURCE(IDB_CURVEBMP) );
}

HRESULT CCSVViewer::Initialize ( 
								LPCITEMIDLIST pidlFolder,
								LPDATAOBJECT pDataObj,
								HKEY hProgID )
{
	TCHAR     szFile    [MAX_PATH];
	UINT      uNumFiles;
	HDROP     hdrop;
	FORMATETC etc = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
	STGMEDIUM stg = { TYMED_HGLOBAL };
	bool      bChangedDir = false;
	
	// Read the list of folders from the data object.  They're stored in HDROP
    // format, so just get the HDROP handle and then use the drag 'n' drop APIs
    // on it.
    if ( FAILED( pDataObj->GetData ( &etc, &stg )))
        return E_INVALIDARG;
	
    // Get an HDROP handle.
    hdrop = (HDROP) GlobalLock ( stg.hGlobal );
	
    if ( NULL == hdrop )
	{
        ReleaseStgMedium ( &stg );
        return E_INVALIDARG;
	}
	
    // Determine how many files are involved in this operation.
    uNumFiles = DragQueryFile ( hdrop, 0xFFFFFFFF, NULL, 0 );
	m_cFiles.clear();
	for ( UINT uFile = 0; uFile < uNumFiles; uFile++ )
    {
        // Get the next filename.
        if ( 0 == DragQueryFile ( hdrop, uFile, szFile, MAX_PATH ))
            continue;
		
		// adding files....
		m_cFiles.push_back(szFile);		
	}
	
    // Release resources.
    GlobalUnlock ( stg.hGlobal );
    ReleaseStgMedium ( &stg );
	
    // If we found any files we can work with, return S_OK.  Otherwise,
    // return E_INVALIDARG so we don't get called again for this right-click
    // operation.
	
    return ( m_cFiles.size() > 0 ) ? S_OK : E_INVALIDARG;
}

HRESULT CCSVViewer::QueryContextMenu (
										 HMENU hmenu,
										 UINT  uMenuIndex,
										 UINT  uidFirstCmd,
										 UINT  uidLastCmd,
										 UINT  uFlags )
{
	UINT uCmdID = uidFirstCmd;
	
    // If the flags include CMF_DEFAULTONLY then we shouldn't do anything.
    if ( uFlags & CMF_DEFAULTONLY )
	{
        return MAKE_HRESULT ( SEVERITY_SUCCESS, FACILITY_NULL, 0 );
	}
	// Add our register/unregister items.
    InsertMenu ( hmenu, uMenuIndex, MF_STRING | MF_BYPOSITION, uCmdID++,
		_T("Plot CSV file(s)") );
	
    // Set the bitmap for the register item.
    if ( NULL != m_hCurveBmp )
	{
        SetMenuItemBitmaps ( hmenu, uMenuIndex, MF_BYPOSITION, m_hCurveBmp, NULL );
	}
	
    uMenuIndex++;
	
	return MAKE_HRESULT ( SEVERITY_SUCCESS, FACILITY_NULL, 2 );
}

HRESULT CCSVViewer::GetCommandString ( 
										 UINT  uCmdID,
										 UINT  uFlags, 
										 UINT* puReserved,
										 LPSTR szName,
										 UINT  cchMax )
{
LPCTSTR szPrompt;

    USES_CONVERSION;

    if ( uFlags & GCS_HELPTEXT )
        {
        switch ( uCmdID )
            {
            case 0:
                szPrompt = _T("Plots CSV files");
            break;
            default:
                ATLASSERT(0);           // should never get here
                return E_INVALIDARG;
            break;
            }

        // Copy the help text into the supplied buffer.  If the shell wants
        // a Unicode string, we need to case szName to an LPCWSTR.

        if ( uFlags & GCS_UNICODE )
           {
            lstrcpynW ( (LPWSTR) szName, T2CW(szPrompt), cchMax );
           }
        else
          {
            lstrcpynA ( szName, T2CA(szPrompt), cchMax );
           }
        }
    else if ( uFlags & GCS_VERB )
        {
        // Copy the verb name into the supplied buffer.  If the shell wants
        // a Unicode string, we need to case szName to an LPCWSTR.

        switch ( uCmdID )
            {
            case 0:
                if ( uFlags & GCS_UNICODE )
                    {
                    lstrcpynW ( (LPWSTR) szName, L"PGLCSV", cchMax );
                    }
                else
                    {
                    lstrcpynA ( szName, "PGLCSV", cchMax );
                    }
            break;

            default:
                ATLASSERT(0);           // should never get here
                return E_INVALIDARG;
            break;
            }
        }

    return S_OK;
}


HRESULT CCSVViewer::InvokeCommand ( LPCMINVOKECOMMANDINFO pCmdInfo )
{
    // If lpVerb really points to a string, ignore this function call and bail out.  

    if ( 0 != HIWORD( pCmdInfo->lpVerb ))
        return E_INVALIDARG;

    // Check that lpVerb is one of our commands (0 or 1)

    switch ( LOWORD( pCmdInfo->lpVerb ))
    {
        case 0:
        case 1:
            return LoadAndPlotFiles();
        break;

        default:
            ATLASSERT(0);               // should never get here
            return E_INVALIDARG;
        break;
        }
}


HRESULT CCSVViewer::LoadAndPlotFiles()
{
	if (m_cFiles.empty())
		return S_OK;
	

	// create PGL Server object
	HRESULT hr;
	CLSID clsid;
	hr=::CLSIDFromProgID(OLESTR("PGLServer.PGLEngine"), &clsid);
	if (FAILED(hr))
		return hr;
		
	CComPtr< IPGLEngine > engine;
	hr=engine.CoCreateInstance(clsid);
	if (FAILED(hr))
		return S_FALSE;

	long rid, lid,oid;
	VARIANT_BOOL vb;
	int ib;
	// creating region
	hr=engine->Region(&rid);
	if (FAILED(hr) || !rid)
		return S_FALSE;
	
	// loading file
	for (int i = m_cFiles.size()-1;i>=0;--i)
	{
		hr=engine->LoadCSVFile(rid, _bstr_t(m_cFiles[i]), &vb);
		if (FAILED(hr))
			return S_FALSE;
	}

	// adding legend
	hr=engine->Legend(rid,&lid);
	if (FAILED(hr))
		return S_FALSE;

	// hiding title, bottom and left labels
	hr=engine->LeftLabel(rid,_bstr_t(""),&oid);
	if (FAILED(hr))
		return S_FALSE;
	hr=engine->Title(rid,_bstr_t(""),&oid);
	if (FAILED(hr))
		return S_FALSE;
	hr=engine->BottomLabel(rid,_bstr_t(""),&oid);
	if (FAILED(hr))
		return S_FALSE;
	
	// setting region name (will be the dialog name)
	hr=engine->Set(rid,_bstr_t("name='CSV File Viewer'"));
	if (FAILED(hr))
		return S_FALSE;
	
	// launching dialog
	hr=engine->DoModalRegion(rid,&ib);
	if (FAILED(hr))
		return S_FALSE;
	

	return S_OK;
}
